﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Application
{
    using System;
    using System.ComponentModel;
    using System.IO;
    using System.Threading;
    using System.Windows.Forms;

    using Mews.Application.Properties;
    using Mews.Net.Nntp.Cache;

    /// <summary>The form that prompts the user about database maintenance.</summary>
    internal sealed partial class MaintenanceForm : TitleForm
    {
        private readonly ThreadStart compactMethod;
        private Thread compactThread;

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal MaintenanceForm(Cache cache) : base(null, Resources.Maintenance, true)
        {
            this.compactMethod = () => this.DoCompact(cache);
            this.InitializeComponent();
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void OnStartNowMenuItem_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            this.startNowMenuItem.Enabled = false;
            this.postponeMenuItem.Enabled = false;
            this.Closing += this.OnMaintenanceForm_Closing;
            this.compactThread = new Thread(this.compactMethod);
            this.compactThread.IsBackground = true;
            this.compactThread.Priority = ThreadPriority.BelowNormal;
            this.compactThread.Start();
        }

        private void OnPostponeMenuItem_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void OnMaintenanceForm_Closing(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }

        private void DoCompact(Cache cache)
        {
            try
            {
                cache.Compact();
                this.BeginInvoke(new Action(
                    () =>
                    {
                        this.Join();
                        this.DialogResult = DialogResult.OK;
                        this.Close();
                    }));
            }
            catch (InsufficientDiskSpaceException)
            {
                this.ShowErrorAsync(Resources.MaintenanceFailedInsufficientDiskSpace);
            }
            catch (IOException)
            {
                this.ShowErrorAsync(Resources.MaintenanceFailedDatabaseLocked);
            }
            catch (MissingComponentException)
            {
                this.ShowErrorAsync(Resources.MaintenanceFailedComponentMissing);
            }
            catch
            {
                this.BeginInvoke(new Action(
                    () =>
                    {
                        this.Join();
                        this.DialogResult = DialogResult.Cancel;
                        this.Close();
                    }));
                throw;
            }
        }

        private void Join()
        {
            this.compactThread.Join();
            this.Closing -= this.OnMaintenanceForm_Closing;
            Cursor.Current = Cursors.Default;
        }

        private void ShowErrorAsync(string text)
        {
            this.BeginInvoke(new Action(
                () =>
                {
                    this.Join();
                    MessageBoxHelper.ShowError(text, Resources.MaintenanceFailedCaption);
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }));
        }
    }
}
